using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 网格布局的滚动框(非复用)
/// </summary>
public class GridScrollBox : MonoBehaviour
{
    [Header("滚动方向")] [SerializeField] private ScrollDirection m_ScrollDir;
    [Header("子项预制体")] [SerializeField] private GameObject m_ItemPrefab;
    [Header("非滚动方向子项个数")] [SerializeField] private int m_LineItemCount = 1;
    public bool IsHorizontal => m_ScrollDir == ScrollDirection.Horizontal;

    public RectTransform m_Content;

    private ScrollRect m_ScrollRect;

    private GridLayoutGroup m_LayoutGroup;

    private float m_ScrollRate;  // 滚动进度, 范围[0, 1], 0: 起始位置, 1: 结束位置
    private float m_ScrollValue;  // cotent相对于viewport的滚动值(滚出了多少)
    private int m_StartShowScrollDirIndex;  // 第一个显示的子项在滚动方向上的索引
    private int m_EndShowScrollDirIndex; // 最后一个显示的子项在滚动方向上的索引
    
    private List<object> m_ItemDataList;
    
    private Dictionary<int, GridScrollBoxItem> m_ShowItemDict;   // key: itemIndex

    private List<object> ItemDataList
    {
        get
        {
            return m_ItemDataList;
        }

        set
        {
            m_ItemDataList = value;
            
            Reload();
        }
    }
    
    private void Awake()
    {
        if (m_Content == null)
        {
            Debug.LogError("Content can not is null");
            return;
        }
        
        m_ShowItemDict = new Dictionary<int, GridScrollBoxItem>();

        m_ScrollRect = GetComponent<ScrollRect>();


        // 设置ScrollRect
        m_ScrollRect.content = m_Content.transform as RectTransform;
        m_ScrollRect.viewport = transform as RectTransform;
        // m_ScrollRect.onValueChanged.AddListener(OnValueChanged);


        m_LayoutGroup = m_ScrollRect.content.GetComponent<GridLayoutGroup>();
        if (IsHorizontal)
        {
            m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedRowCount;
        }
        else
        {
            m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
        }
        m_LayoutGroup.constraintCount = m_LineItemCount;
        
        Test();

    }
    

    private void Test()
    {
        List<string> TestData = new List<string>(100);
        for (int i = 0; i < 10; ++i)
        {
            TestData.Add(i.ToString());
        }

        SetItemData(TestData);
    }

    public void SetItemData<T>(List<T> itemDataList)
    {
        List<object> newItemDataList = new List<object>(itemDataList.Count);
        foreach (T itemData in itemDataList)
        {
            newItemDataList.Add(itemData);
        }

        ItemDataList = newItemDataList;
    }

    public void Reload()
    {
        DestroyAllItem();

        // m_ScrollRect.content.offsetMin = Vector2.zero;
        // m_ScrollRect.content.offsetMax = Vector2.zero;
        

        Vector2 itemSize = m_ItemPrefab.GetComponent<RectTransform>().sizeDelta;
        int scrollDirLineCount = Mathf.CeilToInt(ItemDataList.Count / (float)m_LineItemCount);
        if (IsHorizontal)
        {
            m_ScrollRect.content.sizeDelta = new Vector2(
                m_LayoutGroup.cellSize.x * scrollDirLineCount + m_LayoutGroup.padding.horizontal + m_LayoutGroup.spacing.x * (scrollDirLineCount - 1),
                m_LayoutGroup.cellSize.y);
            
            m_ScrollRect.vertical = false;
        }
        else
        {
            m_ScrollRect.content.sizeDelta = new Vector2(
                m_LayoutGroup.cellSize.x, 
                m_LayoutGroup.cellSize.y * scrollDirLineCount + m_LayoutGroup.padding.vertical + m_LayoutGroup.spacing.y * (scrollDirLineCount - 1));

            m_ScrollRect.horizontal = false;
        }
        
        // 创建Item并存好Item组件
        for (int i = 0; i < m_ItemDataList.Count; ++i)
        {
            GameObject itemGameObject = Instantiate(m_ItemPrefab, m_ScrollRect.content);
            GridScrollBoxItem item = itemGameObject.GetComponent<GridScrollBoxItem>();
            item.OnRefresh(ItemDataList[i]);
            m_ShowItemDict.Add(i, item);
        }
    }

    public GridScrollBoxItem GetItem(int slotIndex)
    {
        GridScrollBoxItem item;
        m_ShowItemDict.TryGetValue(slotIndex, out item);
        return item;
    }

    private void DestroyAllItem()
    {
        foreach (GridScrollBoxItem item in m_ShowItemDict.Values)
        {
            Destroy(item.gameObject);
        }
        m_ShowItemDict.Clear();
    }
}
